from random import choices
from string import ascii_uppercase, digits
import time

from uvicorn import run
from fastapi import FastAPI
from starlette.middleware.cors import CORSMiddleware
from starlette.requests import Request
from starlette.responses import JSONResponse, HTMLResponse
from starlette.staticfiles import StaticFiles
from starlette.templating import Jinja2Templates
from starlette.types import ASGIApp, Scope, Receive, Send

from util.logger import logger


class AuthMiddleware:
    def __init__(self, app: ASGIApp) -> None:
        self.app = app

    async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
        logger.debug(scope.get('path'))
        await self.app(scope, receive, send)


def create_app():

    app = FastAPI(title='贵师大大数据B站舆情分析', description='跟超哥，拿高薪')

    app.add_middleware(AuthMiddleware)  # 这个一定要放到CORSMiddleware前面
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["*"],  # Allows all origins
        allow_credentials=True,
        allow_methods=["*"],  # Allows all methods
        allow_headers=["*"],  # Allows all headers
    )

    api_version = '/api/v1'

    from api.brand.diagnosis import router as brand_diagnosis
    app.include_router(brand_diagnosis, prefix=api_version+"/brand/diagnosis", tags=['品牌评论诊断'])
    from api.brand.launch import router as brand_launch
    app.include_router(brand_launch, prefix=api_version+"/brand/launch", tags=['品牌投放管理'])
    from api.favorite.blogger import router as favorite_blogger
    app.include_router(favorite_blogger, prefix=api_version+"/favorite/blogger", tags=['收藏的UP主'])
    from api.favorite.brand import router as favorite_brand
    app.include_router(favorite_brand, prefix=api_version+"/favorite/brand", tags=['收藏的品牌'])
    from api.favorite.goods import router as favorite_goods
    app.include_router(favorite_goods, prefix=api_version+"/favorite/goods", tags=['收藏的商品'])
    from api.favorite.video import router as favorite_video
    app.include_router(favorite_video, prefix=api_version+"/favorite/video", tags=['收藏的素材'])
    from api.market.industryOverview import router as market_industryOverview
    app.include_router(market_industryOverview, prefix=api_version+"/market/IndustryOverview", tags=['行业大盘'])
    from api.member.workbench import router as member_workbench
    app.include_router(member_workbench, prefix=api_version+"/member/workbench", tags=['工作台'])
    from api.monitor.blogger import router as monitor_blogger
    app.include_router(monitor_blogger, prefix=api_version+"/monitor/blogger", tags=['关注的UP主'])
    from api.monitor.live import router as monitor_live
    app.include_router(monitor_live, prefix=api_version+"/monitor/live", tags=['直播监控'])
    from api.monitor.video import router as monitor_video
    app.include_router(monitor_video, prefix=api_version+"/monitor/video", tags=['视频监控'])
    from api.rank.author import router as rank_author
    app.include_router(rank_author, prefix=api_version+"/rank/author", tags=['达人排行榜'])
    from api.rank.brand import router as rank_brand
    app.include_router(rank_brand, prefix=api_version+"/rank/brand", tags=['品牌排行榜'])
    from api.rank.game import router as rank_game
    app.include_router(rank_game, prefix=api_version+"/rank/game", tags=['手游推广榜'])
    from api.rank.gift import router as rank_gift
    app.include_router(rank_gift, prefix=api_version+"/rank/gift", tags=['礼物排行榜'])
    from api.rank.goods import router as rank_goods
    app.include_router(rank_goods, prefix=api_version+"/rank/goods", tags=['商品排行榜'])
    from api.rank.hotVideo import router as rank_hotVideo
    app.include_router(rank_hotVideo, prefix=api_version+"/rank/hotVideo", tags=['爆款视频榜'])
    from api.rank.live import router as rank_live
    app.include_router(rank_live, prefix=api_version+"/rank/live", tags=['人气排行榜'])
    from api.search.album import router as search_album
    app.include_router(search_album, prefix=api_version+"/search/album", tags=['热门相簿'])
    from api.search.article import router as search_article
    app.include_router(search_article, prefix=api_version+"/search/article", tags=['热门专栏'])
    from api.search.blogger import router as search_blogger
    app.include_router(search_blogger, prefix=api_version+"/search/blogger", tags=['UP主搜索'])
    from api.search.brand import router as search_brand
    app.include_router(search_brand, prefix=api_version+"/search/brand", tags=['品牌搜索'])
    from api.search.game import router as search_game
    app.include_router(search_game, prefix=api_version+"/search/game", tags=['手游搜索'])
    from api.search.goods import router as search_goods
    app.include_router(search_goods, prefix=api_version+"/search/goods", tags=['商品搜索'])
    from api.search.goodsVideo import router as search_goodsVideo
    app.include_router(search_goodsVideo, prefix=api_version+"/search/goodsVideo", tags=['带货视频'])
    from api.search.live import router as search_live
    app.include_router(search_live, prefix=api_version+"/search/live", tags=['直播间搜索'])
    from api.search.price import router as search_price
    app.include_router(search_price, prefix=api_version+"/search/price", tags=['商业报价查询'])
    from api.search.video import router as search_video
    app.include_router(search_video, prefix=api_version+"/search/video", tags=['热门视频'])
    from api.search.videoActivity import router as search_videoActivity
    app.include_router(search_videoActivity, prefix=api_version+"/search/videoActivity", tags=['热门活动'])
    from api.tag.video import router as tag_video
    app.include_router(tag_video, prefix=api_version+"/tag/video", tags=['行业标签榜'])




    return app


app = create_app()



@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    if request.url.path.startswith('/static/'):
        return await call_next(request)
    idem = ''.join(choices(ascii_uppercase + digits, k=8))
    start = time.time()
    logger.info(f"rid={idem}     start request {request.method} path={request.url.path}")

    # logger.debug("Params:")
    # [logger.debug(f"\t{name}: {value}") for name, value in request.path_params.items()]
    #
    # logger.debug("Headers:")
    # [logger.debug(f"\t{name}: {value}") for name, value in request.headers.items()]

    start_time = time.time()

    response = await call_next(request)

    process_time = (time.time() - start_time) * 1000
    formatted_process_time = '{0:.2f}'.format(process_time)

    logger.info(f"rid={idem}     end request elapsed={formatted_process_time}ms status_code={response.status_code}")

    return response


# 全局统一异常处理
async def catch_exceptions_middleware(request: Request, call_next):
    try:
        return await call_next(request)
    except BaseException as e:
        return JSONResponse(status_code=200, content={"status": 400, "msg": f"错误信息：" + str(e), "data": {}})

app.mount("/static", StaticFiles(directory="dist\static"), name="static")
templates = Jinja2Templates(directory="dist")

@app.get('/', response_class=HTMLResponse)
def index(request: Request):
    return templates.TemplateResponse("index.html", {"request": request})

def start():
    run(app='main:app', host='0.0.0.0', port=33333, reload=True, debug=True, log_level='info')


if __name__ == '__main__':
    start()